Create 'composited' label.
authorSøren Sandmann <sandmann@redhat.com>
Tue, 25 Apr 2006 14:27:32 +0000 (14:27 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Tue, 25 Apr 2006 14:27:32 +0000 (14:27 +0000)
Tue Apr 25 10:25:28 2006  Søren Sandmann  <sandmann@redhat.com>

* tests/testgtk.c (create_alpha_window): Create 'composited' label.

* tests/testgtk.c (on_composited_changed): New function, change
the label to say whether the screen is composited or not.

* gtk/gtkwindow.c (gtk_window_on_composited_changed): When
composited status change, invalidate the window and propagate the signal;.

* gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
if reset_type_hint is TRUE.

* gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
the old hints, store a shadow copy in the public window->type_hint
bitfield, otherwise set this field to normal. Set the private
field to the type hint.

* gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.

* gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
"reset_type_hint" indicating whether the type hint needs to be
reset. New field type_hint containing a GdkWindowTypeHint.

* gtk/gtkwidget.c (propagate_composited_changed): New function to
propagate changes in composited status.
(gtk_widget_class_init): Add composited_changed signal.

* gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.

* gtk/gtkwidget.c (gtk_widget_is_composited): New function.

* gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.

* gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint

* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
the item belongs to a menubar. Set the type_hint appropriately
depending on the outcome.

* gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.

* gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
changed on the attach widget.

* gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
set the transient_for property for menus.

* gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.

* gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
transient for the toplevel.

* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
transient-for, for the popup window.

* gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
new window types.

* gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
for new window types.

* gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
New function called whenever the compositing manager comes and goes.

* gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.

* gdk/x11/gdkscreen-x11.c
(_gdk_x11_screen_request_cm_notification, make_cm_atom,
check_is_composited): New functions

* gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
_gdk_x11_screen_process_owner_change when an
XFixesSelectionNotifyEvent is received.

* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
_gdk_x11_screen_request_cm_notification() on all screens.

* gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
implementation.

* gdk/gdkscreen.c (gdk_screen_class_init): New signal,
'composited-changed'.

* gdk/gdkwindow.h: Add new EWMH window types.

* gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)

24 files changed:
ChangeLog
ChangeLog.pre-2-10
gdk/gdkscreen.c
gdk/gdkscreen.h
gdk/gdkwindow.h
gdk/quartz/gdkscreen-quartz.c
gdk/win32/gdkscreen-win32.c
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkevents-x11.c
gdk/x11/gdkscreen-x11.c
gdk/x11/gdkscreen-x11.h
gdk/x11/gdkwindow-x11.c
gtk/gtkcombo.c
gtk/gtkcombobox.c
gtk/gtkdnd.c
gtk/gtkmenu.c
gtk/gtkmenuitem.c
gtk/gtkmenuitem.h
gtk/gtktooltips.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/gtkwindow.h
tests/testgtk.c

index ef2b50008f27039e9337d2b45a4dafef092fe4fb..27345cf57b1ef444efa2d7690f366de780677384 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,91 @@
+Tue Apr 25 10:25:28 2006  Søren Sandmann  <sandmann@redhat.com>
+
+       * tests/testgtk.c (create_alpha_window): Create 'composited' label.
+
+       * tests/testgtk.c (on_composited_changed): New function, change
+       the label to say whether the screen is composited or not.
+
+       * gtk/gtkwindow.c (gtk_window_on_composited_changed): When
+       composited status change, invalidate the window and propagate the signal;.
+
+       * gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
+       if reset_type_hint is TRUE.
+
+       * gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
+       the old hints, store a shadow copy in the public window->type_hint
+       bitfield, otherwise set this field to normal. Set the private
+       field to the type hint.
+
+       * gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint. 
+
+       * gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
+       "reset_type_hint" indicating whether the type hint needs to be
+       reset. New field type_hint containing a GdkWindowTypeHint.
+
+       * gtk/gtkwidget.c (propagate_composited_changed): New function to
+       propagate changes in composited status.
+       (gtk_widget_class_init): Add composited_changed signal.
+       
+       * gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
+
+       * gtk/gtkwidget.c (gtk_widget_is_composited): New function.
+
+       * gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
+
+       * gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
+
+       * gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
+       the item belongs to a menubar. Set the type_hint appropriately
+       depending on the outcome.
+
+       * gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
+
+       * gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
+       changed on the attach widget.
+
+       * gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
+       set the transient_for property for menus.
+
+       * gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
+
+       * gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
+       transient for the toplevel.
+
+       * gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
+       transient-for, for the popup window.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
+       new window types.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
+       for new window types.
+
+       * gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
+       New function called whenever the compositing manager comes and goes.
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
+
+       * gdk/x11/gdkscreen-x11.c
+       (_gdk_x11_screen_request_cm_notification, make_cm_atom,
+       check_is_composited): New functions
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
+       _gdk_x11_screen_process_owner_change when an
+       XFixesSelectionNotifyEvent is received.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
+       _gdk_x11_screen_request_cm_notification() on all screens.
+
+       * gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
+       implementation. 
+
+       * gdk/gdkscreen.c (gdk_screen_class_init): New signal,
+       'composited-changed'.
+
+       * gdk/gdkwindow.h: Add new EWMH window types.
+
+       * gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited) 
+
 2006-04-25  Matthias Clasen  <mclasen@redhat.com>
 
        * modules/printbackends/cups/gtkprintbackendcups.c: 
        * gtk/gtkprinter.c:
        Don't ref the backend since the backend owns the printer.
 
+>>>>>>> 1.7779
 2006-04-24  Alexander Larsson  <alexl@redhat.com>
 
        * gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
index ef2b50008f27039e9337d2b45a4dafef092fe4fb..27345cf57b1ef444efa2d7690f366de780677384 100644 (file)
@@ -1,3 +1,91 @@
+Tue Apr 25 10:25:28 2006  Søren Sandmann  <sandmann@redhat.com>
+
+       * tests/testgtk.c (create_alpha_window): Create 'composited' label.
+
+       * tests/testgtk.c (on_composited_changed): New function, change
+       the label to say whether the screen is composited or not.
+
+       * gtk/gtkwindow.c (gtk_window_on_composited_changed): When
+       composited status change, invalidate the window and propagate the signal;.
+
+       * gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
+       if reset_type_hint is TRUE.
+
+       * gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
+       the old hints, store a shadow copy in the public window->type_hint
+       bitfield, otherwise set this field to normal. Set the private
+       field to the type hint.
+
+       * gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint. 
+
+       * gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
+       "reset_type_hint" indicating whether the type hint needs to be
+       reset. New field type_hint containing a GdkWindowTypeHint.
+
+       * gtk/gtkwidget.c (propagate_composited_changed): New function to
+       propagate changes in composited status.
+       (gtk_widget_class_init): Add composited_changed signal.
+       
+       * gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
+
+       * gtk/gtkwidget.c (gtk_widget_is_composited): New function.
+
+       * gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
+
+       * gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
+
+       * gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
+       the item belongs to a menubar. Set the type_hint appropriately
+       depending on the outcome.
+
+       * gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
+
+       * gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
+       changed on the attach widget.
+
+       * gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
+       set the transient_for property for menus.
+
+       * gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
+
+       * gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
+       transient for the toplevel.
+
+       * gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
+       transient-for, for the popup window.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
+       new window types.
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
+       for new window types.
+
+       * gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
+       New function called whenever the compositing manager comes and goes.
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
+
+       * gdk/x11/gdkscreen-x11.c
+       (_gdk_x11_screen_request_cm_notification, make_cm_atom,
+       check_is_composited): New functions
+
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
+       _gdk_x11_screen_process_owner_change when an
+       XFixesSelectionNotifyEvent is received.
+
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
+       _gdk_x11_screen_request_cm_notification() on all screens.
+
+       * gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
+       implementation. 
+
+       * gdk/gdkscreen.c (gdk_screen_class_init): New signal,
+       'composited-changed'.
+
+       * gdk/gdkwindow.h: Add new EWMH window types.
+
+       * gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited) 
+
 2006-04-25  Matthias Clasen  <mclasen@redhat.com>
 
        * modules/printbackends/cups/gtkprintbackendcups.c: 
        * gtk/gtkprinter.c:
        Don't ref the backend since the backend owns the printer.
 
+>>>>>>> 1.7779
 2006-04-24  Alexander Larsson  <alexl@redhat.com>
 
        * gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
index 6f531a96f0a6a225a01827a0ceb275fa383b2fac..924ef531d0fd6d7dc04e1131ce44ee94714c3151 100644 (file)
@@ -50,6 +50,7 @@ enum
 enum
 {
   SIZE_CHANGED,
+  COMPOSITED_CHANGED,
   LAST_SIGNAL
 };
 
@@ -104,6 +105,25 @@ gdk_screen_class_init (GdkScreenClass *klass)
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE,
                   0);
+
+  /**
+   * GdkScreen::composited-changed:
+   * @screen: the object on which the signal is emitted
+   *
+   * The ::composited_changed signal is emitted when the composited
+   * status of the screen changes
+   *
+   * Since: 2.10
+   */
+  signals[COMPOSITED_CHANGED] =
+    g_signal_new (g_intern_static_string ("composited_changed"),
+                 G_OBJECT_CLASS_TYPE (klass),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GdkScreenClass, composited_changed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE,
+                 0);
 }
 
 static void
index 3b6624b687d138731742a65f0815ccd974f351fe..7ff920193fa86e29979f6de83c935e9cd84122a6 100644 (file)
@@ -57,6 +57,7 @@ struct _GdkScreenClass
   GObjectClass parent_class;
 
   void (*size_changed) (GdkScreen *screen);
+  void (*composited_changed) (GdkScreen *screen);
 };
 
 GType        gdk_screen_get_type              (void) G_GNUC_CONST;
@@ -69,7 +70,7 @@ GdkColormap *gdk_screen_get_rgb_colormap      (GdkScreen   *screen);
 GdkVisual *  gdk_screen_get_rgb_visual        (GdkScreen   *screen);
 GdkColormap *gdk_screen_get_rgba_colormap     (GdkScreen   *screen);
 GdkVisual *  gdk_screen_get_rgba_visual       (GdkScreen   *screen);
-
+gboolean     gdk_screen_is_composited        (GdkScreen   *screen);
 
 GdkWindow *  gdk_screen_get_root_window       (GdkScreen   *screen);
 GdkDisplay * gdk_screen_get_display           (GdkScreen   *screen);
index 4ff4847e16b4172f65416c7f2f4968a2d9d5e9c6..b0962bcfde8f1be072eab804753bf6a7c0bbe699 100644 (file)
@@ -127,15 +127,20 @@ typedef enum
 {
   GDK_WINDOW_TYPE_HINT_NORMAL,
   GDK_WINDOW_TYPE_HINT_DIALOG,
-  GDK_WINDOW_TYPE_HINT_MENU,
+  GDK_WINDOW_TYPE_HINT_MENU,           /* Torn off menu */
   GDK_WINDOW_TYPE_HINT_TOOLBAR,
   GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
   GDK_WINDOW_TYPE_HINT_UTILITY,
   GDK_WINDOW_TYPE_HINT_DOCK,
-  GDK_WINDOW_TYPE_HINT_DESKTOP
+  GDK_WINDOW_TYPE_HINT_DESKTOP,
+  GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU,  /* A drop down menu (from a menubar) */
+  GDK_WINDOW_TYPE_HINT_POPUP_MENU,     /* A popup menu (from right-click) */
+  GDK_WINDOW_TYPE_HINT_TOOLTIP,
+  GDK_WINDOW_TYPE_HINT_NOTIFICATION,
+  GDK_WINDOW_TYPE_HINT_COMBO,
+  GDK_WINDOW_TYPE_HINT_DND
 } GdkWindowTypeHint;
 
-
 /* The next two enumeration values current match the
  * Motif constants. If this is changed, the implementation
  * of gdk_window_set_decorations/gdk_window_set_functions
index 3aadebd06366540de2ac95be07b38d4e7c299a5d..c1484256fa28e6f71c4175c6c65db345f38f38f1 100644 (file)
@@ -255,3 +255,11 @@ gdk_screen_get_window_stack (GdkScreen *screen)
 
   return NULL;
 }
+
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+  return TRUE;
+}
index 0bf47e3dcfe7c78159d775ba9f5429762e16ceaa..ea16a64046c05ae4d6654d5f3e769d71d4e389ff 100644 (file)
@@ -133,3 +133,11 @@ gdk_screen_get_window_stack (GdkScreen *screen)
 
   return NULL;
 }
+
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+  return FALSE;
+}
index e082500b4ba8f078bfd8544a954d464992a9ad94..6034379c09e4dcd95bc64129e10fed42453c62ae 100644 (file)
@@ -77,6 +77,7 @@ static const char *const precache_atoms[] = {
   "WM_LOCALE_NAME",
   "WM_PROTOCOLS",
   "WM_TAKE_FOCUS",
+  "_NET_WM_CM_S0",
   "_NET_WM_DESKTOP",
   "_NET_WM_ICON",
   "_NET_WM_ICON_NAME",
@@ -311,6 +312,9 @@ gdk_display_open (const gchar *display_name)
   _gdk_input_init (display);
   _gdk_dnd_init (display);
 
+  for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
+    _gdk_x11_screen_request_cm_notification (display_x11->screens[i]);
+
   g_signal_emit_by_name (gdk_display_manager_get(),
                         "display_opened", display);
 
@@ -1102,8 +1106,9 @@ gdk_display_supports_selection_notification (GdkDisplay *display)
  *
  * Since: 2.6
  **/
-gboolean gdk_display_request_selection_notification  (GdkDisplay *display,
-                                                     GdkAtom     selection)
+gboolean
+gdk_display_request_selection_notification  (GdkDisplay *display,
+                                            GdkAtom     selection)
 
 {
 #ifdef HAVE_XFIXES
index 40bce56b30b0493e6e9c5e6a4b9ecae7ffdde733..46cdd12857f174d8478dab5a4af98b250bd354e4 100644 (file)
@@ -2077,6 +2077,9 @@ gdk_event_translate (GdkDisplay *display,
       if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
        {
          XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+
+         _gdk_x11_screen_process_owner_change (screen, xevent);
+         
          event->owner_change.type = GDK_OWNER_CHANGE;
          event->owner_change.window = window;
          event->owner_change.owner = selection_notify->owner;
@@ -2086,7 +2089,7 @@ gdk_event_translate (GdkDisplay *display,
                                               selection_notify->selection);
          event->owner_change.time = selection_notify->timestamp;
          event->owner_change.selection_time = selection_notify->selection_timestamp;
-
+         
          return_val = TRUE;
        }
       else
index 3efb0559d5fef05ba4045d302266940b9891b11f..70e623a5a0765afbceca49faec1cfd530f1488e7 100644 (file)
 #include <X11/extensions/Xrandr.h>
 #endif
 
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
 static void         gdk_screen_x11_dispose     (GObject                  *object);
 static void         gdk_screen_x11_finalize    (GObject                  *object);
 static void        init_xinerama_support      (GdkScreen         *screen);
@@ -460,6 +464,27 @@ gdk_x11_screen_get_screen_number (GdkScreen *screen)
   return GDK_SCREEN_X11 (screen)->screen_num;
 }
 
+static gboolean
+check_is_composited (GdkDisplay *display,
+                    GdkScreenX11 *screen_x11)
+{
+  Atom xselection = gdk_x11_atom_to_xatom_for_display (display, screen_x11->cm_selection_atom);
+  Window xwindow;
+  
+  xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), xselection);
+
+  return xwindow != None;
+}
+
+static GdkAtom
+make_cm_atom (int screen_number)
+{
+  gchar *name = g_strdup_printf ("_NET_WM_CM_S%d", screen_number);
+  GdkAtom atom = gdk_atom_intern (name, FALSE);
+  g_free (name);
+  return atom;
+}
+
 GdkScreen *
 _gdk_x11_screen_new (GdkDisplay *display,
                     gint        screen_number) 
@@ -479,16 +504,52 @@ _gdk_x11_screen_new (GdkDisplay *display,
   screen_x11->wmspec_check_window = None;
   /* we want this to be always non-null */
   screen_x11->window_manager_name = g_strdup ("unknown");
+  screen_x11->cm_selection_atom = make_cm_atom (screen_number);
+  screen_x11->is_composited = check_is_composited (display, screen_x11);
   
   init_xinerama_support (screen);
   init_randr_support (screen);
   
   _gdk_visual_init (screen);
   _gdk_windowing_window_init (screen);
-
+  
   return screen;
 }
 
+void
+_gdk_x11_screen_request_cm_notification (GdkScreenX11 *screen_x11)
+{
+  gdk_display_request_selection_notification (screen_x11->display, screen_x11->cm_selection_atom);
+}
+
+/**
+ * gdk_screen_is_composited:
+ * @screen: a #GdkScreen
+ * 
+ * Returns whether windows with an RGBA visual can reasonably
+ * be expected to have their alpha channel drawn correctly on
+ * the screen.
+ *
+ * On X11 this function returns whether a compositing manager is
+ * compositing @screen.
+ * 
+ * Return value: Whether windows with RGBA visuals can reasonably be
+ * expected to have their alpha channels drawn correctly on the screen.
+ * 
+ * Since: 2.10
+ **/
+gboolean
+gdk_screen_is_composited (GdkScreen *screen)
+{
+  GdkScreenX11 *screen_x11;
+
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+  screen_x11 = GDK_SCREEN_X11 (screen);
+
+  return screen_x11->is_composited;
+}
+
 #ifdef HAVE_XINERAMA
 static gboolean
 check_solaris_xinerama (GdkScreen *screen)
@@ -705,6 +766,28 @@ _gdk_x11_screen_window_manager_changed (GdkScreen *screen)
   g_signal_emit (screen, signals[WINDOW_MANAGER_CHANGED], 0);
 }
 
+void
+_gdk_x11_screen_process_owner_change (GdkScreen *screen,
+                                     XEvent *event)
+{
+  XFixesSelectionNotifyEvent *selection_event = (XFixesSelectionNotifyEvent *)event;
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+  Atom xcm_selection_atom = gdk_x11_atom_to_xatom_for_display (screen_x11->display,
+                                                              screen_x11->cm_selection_atom);
+
+  if (selection_event->selection == xcm_selection_atom)
+    {
+      gboolean composited = selection_event->owner != None;
+
+      if (composited != screen_x11->is_composited)
+       {
+         screen_x11->is_composited = composited;
+
+         g_signal_emit_by_name (screen, "composited_changed");
+       }
+    }
+}
+
 /**
  * _gdk_windowing_substitute_screen_number:
  * @display_name : The name of a display, in the form used by 
index 5ea82a4fbccd0e252aeffbedafab65c182b8e317..6ba8d62999c7096335cfdae69f0a7dc071d03988 100644 (file)
@@ -103,6 +103,9 @@ struct _GdkScreenX11
   gint xft_hintstyle;
   gint xft_rgba;
   gint xft_dpi;
+
+  GdkAtom cm_selection_atom;
+  gboolean is_composited;
 };
   
 struct _GdkScreenX11Class
@@ -119,6 +122,8 @@ GdkScreen * _gdk_x11_screen_new      (GdkDisplay *display,
 void _gdk_x11_screen_window_manager_changed (GdkScreen *screen);
 void _gdk_x11_screen_size_changed           (GdkScreen *screen,
                                             XEvent    *event);
+void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
+                                          XEvent    *event);
 
 G_END_DECLS
 
index 384711ce4f32e1c03cb916c9ce583cd35bd47314..52a85c71ee53409ef61486d012f85a4f12eb0f19 100644 (file)
@@ -2226,6 +2226,24 @@ gdk_window_set_type_hint (GdkWindow        *window,
     case GDK_WINDOW_TYPE_HINT_DESKTOP:
       atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
       break;
+    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
+      break;
+    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
+      break;
+    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
+      break;
+    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
+      break;
+    case GDK_WINDOW_TYPE_HINT_COMBO:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
+      break;
+    case GDK_WINDOW_TYPE_HINT_DND:
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
+      break;
     default:
       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
       /* Fall thru */
@@ -2295,6 +2313,18 @@ gdk_window_get_type_hint (GdkWindow *window)
             type = GDK_WINDOW_TYPE_HINT_DOCK;
           else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
             type = GDK_WINDOW_TYPE_HINT_DESKTOP;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
+           type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
+           type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
+           type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
+           type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
+           type = GDK_WINDOW_TYPE_HINT_COMBO;
+         else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
+           type = GDK_WINDOW_TYPE_HINT_DND;
         }
 
       if (type_return != None && data != NULL)
index a5b7b17a7c6431692a7f0b2ba1e42298dc772d46..345780f39a6849019dd7574c09e8a7bbb979bdac 100644 (file)
@@ -564,6 +564,7 @@ gtk_combo_popup_list (GtkCombo *combo)
     {
       gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), 
                                    GTK_WINDOW (combo->popwin));
+      gtk_window_set_transient_for (combo->popwin, GTK_WINDOW (toplevel));
     }
 
   gtk_widget_set_size_request (combo->popwin, width, height);
@@ -941,6 +942,7 @@ gtk_combo_init (GtkCombo * combo)
                    G_CALLBACK (gtk_combo_popup_button_leave), combo);
 
   combo->popwin = gtk_window_new (GTK_WINDOW_POPUP);
+  gtk_window_set_type_hint (GTK_WINDOW (combo->popwin), GDK_WINDOW_TYPE_HINT_COMBO);
   g_object_ref (combo->popwin);
   gtk_window_set_resizable (GTK_WINDOW (combo->popwin), FALSE);
 
index eb730a5b87f60210a92a9eb3c8ca86492e7031c1..640661aa90c801a8a546f67b0401dd1b68463ce9 100644 (file)
@@ -1220,6 +1220,9 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
          
           combo_box->priv->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
 
+         gtk_window_set_type_hint (GTK_WINDOW (combo_box->priv->popup_window),
+                                   GDK_WINDOW_TYPE_HINT_COMBO);
+
          g_signal_connect (GTK_WINDOW(combo_box->priv->popup_window),"show",
                            G_CALLBACK (gtk_combo_box_child_show),
                            combo_box);
@@ -1229,8 +1232,12 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
          
          toplevel = gtk_widget_get_toplevel (GTK_WIDGET (combo_box));
          if (GTK_IS_WINDOW (toplevel))
-           gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), 
-                                        GTK_WINDOW (combo_box->priv->popup_window));
+           {
+             gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), 
+                                          GTK_WINDOW (combo_box->priv->popup_window));
+             gtk_window_set_transient_for (GTK_WINDOW (combo_box->priv->popup_window),
+                                           GTK_WINDOW (toplevel));
+           }
 
          gtk_window_set_resizable (GTK_WINDOW (combo_box->priv->popup_window), FALSE);
           gtk_window_set_screen (GTK_WINDOW (combo_box->priv->popup_window),
index c7aeea1806528206ddcb57114f95c426e6d3809a..8c2d2abc7666816a2db4c8453d79cc12abd7826b 100644 (file)
@@ -2938,6 +2938,7 @@ set_icon_stock_pixbuf (GdkDragContext    *context,
   /* Push a NULL colormap to guard against gtk_widget_push_colormap() */
   gtk_widget_push_colormap (NULL);
   window = gtk_window_new (GTK_WINDOW_POPUP);
+  gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
   gtk_window_set_screen (GTK_WINDOW (window), screen);
   set_can_change_screen (window, TRUE);
   gtk_widget_pop_colormap ();
@@ -3083,6 +3084,7 @@ gtk_drag_set_icon_pixmap (GdkDragContext    *context,
   gtk_widget_push_colormap (colormap);
 
   window = gtk_window_new (GTK_WINDOW_POPUP);
+  gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DND);
   gtk_window_set_screen (GTK_WINDOW (window), screen);
   set_can_change_screen (window, FALSE);
   gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
index cb406b2680e7d89da6de172185ed60276272ca33..68d1e71a527ceacff9cb9aead8cbf6354648fe4f 100644 (file)
@@ -1036,6 +1036,33 @@ attach_widget_screen_changed (GtkWidget *attach_widget,
     }
 }
 
+static void
+attach_widget_hierarchy_changed (GtkWidget *attach_widget,
+                                GtkWidget *previous_toplevel,
+                                gpointer data)
+{
+  GtkMenu *menu = GTK_MENU (data);
+  GtkWidget *new_toplevel = gtk_widget_get_toplevel (attach_widget);
+
+  if (g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen"))
+    {
+      /* If there is an explicit screen set, then don't set WM_TRANSIENT_FOR.
+       * Because, what would happen if the attach widget moved to a different
+       * screen on a different display? The menu wouldn't move along with it,
+       * so we just make it the responsibility of whoever set the screen to
+       * also set WM_TRANSIENT_FOR.
+       */
+      return;
+    }
+  
+  if (menu->toplevel && !g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen") &&
+      (!new_toplevel || GTK_IS_WINDOW (new_toplevel)))
+    {
+      gtk_window_set_transient_for (GTK_WINDOW (menu->toplevel),
+                                   GTK_WINDOW (new_toplevel));
+    }
+}
+
 void
 gtk_menu_attach_to_widget (GtkMenu            *menu,
                           GtkWidget           *attach_widget,
@@ -1067,6 +1094,10 @@ gtk_menu_attach_to_widget (GtkMenu              *menu,
                    G_CALLBACK (attach_widget_screen_changed), menu);
   attach_widget_screen_changed (attach_widget, NULL, menu);
   
+  g_signal_connect (attach_widget, "hierarchy_changed",
+                   G_CALLBACK (attach_widget_hierarchy_changed), menu);
+  attach_widget_hierarchy_changed (attach_widget, NULL, menu);
+  
   data->detacher = detacher;
   g_object_set_data (G_OBJECT (menu), I_(attach_data_key), data);
   list = g_object_steal_data (G_OBJECT (attach_widget), ATTACHED_MENUS);
@@ -1121,6 +1152,10 @@ gtk_menu_detach (GtkMenu *menu)
   g_signal_handlers_disconnect_by_func (data->attach_widget,
                                        (gpointer) attach_widget_screen_changed,
                                        menu);
+  g_signal_handlers_disconnect_by_func (data->attach_widget,
+                                       (gpointer) attach_widget_hierarchy_changed,
+                                       menu);
+  attach_widget_hierarchy_changed (data->attach_widget, NULL, menu);
 
   if (data->detacher)
     data->detacher (data->attach_widget, menu);
@@ -1836,7 +1871,6 @@ gtk_menu_set_tearoff_state (GtkMenu  *menu,
                                                     "app-paintable", TRUE,
                                                     NULL);
 
-             
              gtk_window_set_type_hint (GTK_WINDOW (menu->tearoff_window),
                                        GDK_WINDOW_TYPE_HINT_MENU);
              gtk_window_set_mnemonic_modifier (GTK_WINDOW (menu->tearoff_window), 0);
@@ -3765,6 +3799,10 @@ gtk_menu_position (GtkMenu *menu)
   private->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
 
   private->initially_pushed_in = FALSE;
+
+  /* Set the type hint here to allow custom position functions to set a different hint */
+  if (!GTK_WIDGET_VISIBLE (menu->toplevel))
+    gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
   
   if (menu->position_func)
     {
index b58e13612ecf5fe5d542d967a4e8a3f9b3fabd7d..3b3d346c59360c7be3b449a38e607b6f8fec61a6 100644 (file)
@@ -1122,7 +1122,7 @@ gtk_menu_item_position_menu (GtkMenu  *menu,
 {
   GtkMenuItem *menu_item;
   GtkWidget *widget;
-  GtkWidget *parent_menu_item;
+  GtkMenuItem *parent_menu_item;
   GdkScreen *screen;
   gint twidth, theight;
   gint tx, ty;
@@ -1164,6 +1164,22 @@ gtk_menu_item_position_menu (GtkMenu  *menu,
   ty += widget->allocation.y;
 
   get_offsets (menu, &horizontal_offset, &vertical_offset);
+
+  if (GTK_IS_MENU_BAR (widget->parent))
+    {
+      menu_item->from_menubar = TRUE;
+    }
+  else if (GTK_IS_MENU (widget->parent))
+    {
+      if (GTK_MENU (widget->parent)->parent_menu_item)
+       menu_item->from_menubar = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item)->from_menubar;
+      else
+       menu_item->from_menubar = FALSE;
+    }
+  else
+    {
+      menu_item->from_menubar = FALSE;
+    }
   
   switch (menu_item->submenu_placement)
     {
@@ -1175,7 +1191,6 @@ gtk_menu_item_position_menu (GtkMenu  *menu,
          menu_item->submenu_direction = GTK_DIRECTION_LEFT;
          tx += widget->allocation.width - twidth;
        }
-
       if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height)
        ty += widget->allocation.height;
       else if ((ty - theight) >= monitor.y)
@@ -1188,16 +1203,23 @@ gtk_menu_item_position_menu (GtkMenu  *menu,
 
     case GTK_LEFT_RIGHT:
       if (GTK_IS_MENU (widget->parent))
-       parent_menu_item = GTK_MENU (widget->parent)->parent_menu_item;
+       parent_menu_item = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item);
       else
        parent_menu_item = NULL;
+      
       parent_xthickness = widget->parent->style->xthickness;
+
       if (parent_menu_item && !GTK_MENU (widget->parent)->torn_off)
-       menu_item->submenu_direction = GTK_MENU_ITEM (parent_menu_item)->submenu_direction;
-      else if (direction == GTK_TEXT_DIR_LTR)
-       menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+       {
+         menu_item->submenu_direction = parent_menu_item->submenu_direction;
+       }
       else
-       menu_item->submenu_direction = GTK_DIRECTION_LEFT;
+       {
+         if (direction == GTK_TEXT_DIR_LTR)
+           menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+         else
+           menu_item->submenu_direction = GTK_DIRECTION_LEFT;
+       }
 
       switch (menu_item->submenu_direction)
        {
@@ -1236,6 +1258,12 @@ gtk_menu_item_position_menu (GtkMenu  *menu,
   *y = ty;
 
   gtk_menu_set_monitor (menu, monitor_num);
+
+  if (!GTK_WIDGET_VISIBLE (menu->toplevel))
+    {
+      gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), menu_item->from_menubar?
+                               GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU : GDK_WINDOW_TYPE_HINT_POPUP_MENU);
+    }
 }
 
 /**
index 0d7a42e9ded27ca1b647cb0a0f4abbd47ed6181d..e76087b6018f95c718a3a3f935df8f23802d80a3 100644 (file)
@@ -61,6 +61,7 @@ struct _GtkMenuItem
   guint submenu_direction : 1;
   guint right_justify: 1;
   guint timer_from_keypress : 1;
+  guint from_menubar : 1;
   guint timer;
 };
 
index ed505915cea47cc9999aca9bc2bb7abb7f9974a5..be47d7303622c44e12ed711d19700108b8677f90 100644 (file)
@@ -249,6 +249,7 @@ gtk_tooltips_force_window (GtkTooltips *tooltips)
   if (!tooltips->tip_window)
     {
       tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP);
+      gtk_window_set_type_hint (GTK_WINDOW (tooltips->tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
       gtk_tooltips_update_screen (tooltips, TRUE);
       gtk_widget_set_app_paintable (tooltips->tip_window, TRUE);
       gtk_window_set_resizable (GTK_WINDOW (tooltips->tip_window), FALSE);
@@ -405,6 +406,7 @@ gtk_tooltips_draw_tips (GtkTooltips *tooltips)
   GdkScreen *pointer_screen;
   gint monitor_num, px, py;
   GdkRectangle monitor;
+  GtkWindow *toplevel;
 
   if (!tooltips->tip_window)
     gtk_tooltips_force_window (tooltips);
@@ -466,6 +468,10 @@ gtk_tooltips_draw_tips (GtkTooltips *tooltips)
   else
     y = y + widget->allocation.height + 4;
 
+  toplevel = gtk_widget_get_toplevel (widget);
+  if (toplevel && GTK_IS_WINDOW (toplevel))
+    gtk_window_set_transient_for (tooltips->tip_window, toplevel);
+  
   gtk_window_move (GTK_WINDOW (tooltips->tip_window), x, y);
   gtk_widget_show (tooltips->tip_window);
 }
index 194caa0ee2af8e063b7fd9b84298586eb3c7c661..37747c81d8bdf7f257f931e47ca1e257d8f82f68 100644 (file)
@@ -121,6 +121,7 @@ enum {
   SCREEN_CHANGED,
   CAN_ACTIVATE_ACCEL,
   GRAB_BROKEN,
+  COMPOSITED_CHANGED,
   LAST_SIGNAL
 };
 
@@ -787,6 +788,14 @@ gtk_widget_class_init (GtkWidgetClass *klass)
                  _gtk_marshal_BOOLEAN__BOXED,
                  G_TYPE_BOOLEAN, 1,
                  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+  widget_signals[COMPOSITED_CHANGED] =
+    g_signal_new (I_("composited_changed"),
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                 G_STRUCT_OFFSET (GtkWidgetClass, composited_changed),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
 
 /**
  * GtkWidget::delete-event:
@@ -5157,6 +5166,49 @@ gtk_widget_propagate_screen_changed_recurse (GtkWidget *widget,
   g_object_unref (widget);
 }
 
+/**
+ * gtk_widget_is_composited:
+ * @widget: 
+ * 
+ * Whether @widget can rely on having its alpha channel
+ * drawn correctly. On X11 this function returns whether a
+ * compositing manager is running for @widget's screen
+ * 
+ * Return value: #TRUE if the widget can rely on its alpha
+ * channel being drawn correctly.
+ * 
+ * Since: 2.10
+ **/
+gboolean
+gtk_widget_is_composited (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+  
+  GdkScreen *screen = gtk_widget_get_screen (widget);
+  
+  return gdk_screen_is_composited (screen);
+}
+
+static void
+propagate_composited_changed (GtkWidget *widget,
+                             gpointer dummy)
+{
+  if (GTK_IS_CONTAINER (widget))
+    {
+      gtk_container_forall (GTK_CONTAINER (widget),
+                           propagate_composited_changed,
+                           NULL);
+    }
+  
+  g_signal_emit (widget, widget_signals[COMPOSITED_CHANGED], 0);
+}
+
+void
+_gtk_widget_propagate_composited_changed (GtkWidget *widget)
+{
+  propagate_composited_changed (widget, NULL);
+}
+
 /**
  * _gtk_widget_propagate_screen_changed:
  * @widget: a #GtkWidget
index d161bbebb3a28ce0e814b32723414a58823d93f6..7cfc3df5cd37fc6028a63129443384dad18d5fa3 100644 (file)
@@ -407,8 +407,9 @@ struct _GtkWidgetClass
   gboolean (*grab_broken_event) (GtkWidget          *widget,
                                  GdkEventGrabBroken  *event);
 
+  void         (* composited_changed) (GtkWidget *widget);
+       
   /* Padding for future expansion */
-  void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
   void (*_gtk_reserved5) (void);
   void (*_gtk_reserved6) (void);
@@ -738,6 +739,9 @@ GtkTextDirection gtk_widget_get_direction         (GtkWidget        *widget);
 void             gtk_widget_set_default_direction (GtkTextDirection  dir);
 GtkTextDirection gtk_widget_get_default_direction (void);
 
+/* Compositing manager functionality */
+gboolean gtk_widget_is_composited (GtkWidget *widget);
+
 /* Counterpart to gdk_window_shape_combine_mask.
  */
 void        gtk_widget_shape_combine_mask (GtkWidget *widget,
@@ -788,6 +792,7 @@ void              _gtk_widget_propagate_hierarchy_changed (GtkWidget    *widget,
                                                           GtkWidget    *previous_toplevel);
 void              _gtk_widget_propagate_screen_changed    (GtkWidget    *widget,
                                                           GdkScreen    *previous_screen);
+void             _gtk_widget_propagate_composited_changed (GtkWidget    *widget);
 
 GdkColormap* _gtk_widget_peek_colormap (void);
 
index d59ff6553f88c8cfb4d0be66dc62a5bd12539e80..82cc51dbe079b3d2ae693bcfeca20e8a8107500b 100644 (file)
@@ -172,6 +172,9 @@ struct _GtkWindowPrivate
   guint accept_focus : 1;
   guint focus_on_map : 1;
   guint deletable : 1;
+
+  guint reset_type_hint : 1;
+  GdkWindowTypeHint type_hint;
 };
 
 static void gtk_window_class_init         (GtkWindowClass    *klass);
@@ -279,6 +282,8 @@ static void     gtk_window_unrealize_icon             (GtkWindow    *window);
 static void        gtk_window_notify_keys_changed (GtkWindow   *window);
 static GtkKeyHash *gtk_window_get_key_hash        (GtkWindow   *window);
 static void        gtk_window_free_key_hash       (GtkWindow   *window);
+static void       gtk_window_on_composited_changed (GdkScreen *screen,
+                                                    GtkWindow *window);
 
 static GSList      *toplevel_list = NULL;
 static GtkBinClass *parent_class = NULL;
@@ -815,6 +820,7 @@ gtk_window_init (GtkWindow *window)
   priv->accept_focus = TRUE;
   priv->focus_on_map = TRUE;
   priv->deletable = TRUE;
+  priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
 
   colormap = _gtk_widget_peek_colormap ();
   if (colormap)
@@ -826,6 +832,8 @@ gtk_window_init (GtkWindow *window)
 
   gtk_decorated_window_init (window);
 
+  g_signal_connect (window->screen, "composited_changed",
+                   G_CALLBACK (gtk_window_on_composited_changed), window);
 }
 
 static void
@@ -937,9 +945,11 @@ gtk_window_get_property (GObject      *object,
                         GParamSpec   *pspec)
 {
   GtkWindow  *window;
+  GtkWindowPrivate *priv;
 
   window = GTK_WINDOW (object);
-
+  priv = GTK_WINDOW_GET_PRIVATE (window);
+  
   switch (prop_id)
     {
       GtkWindowGeometryInfo *info;
@@ -1000,8 +1010,7 @@ gtk_window_get_property (GObject      *object,
       g_value_set_boolean (value, window->has_toplevel_focus);
       break;
     case PROP_TYPE_HINT:
-      g_value_set_enum (value,
-                        window->type_hint);
+      g_value_set_enum (value, priv->type_hint);
       break;
     case PROP_SKIP_TASKBAR_HINT:
       g_value_set_boolean (value,
@@ -1980,9 +1989,20 @@ void
 gtk_window_set_type_hint (GtkWindow           *window, 
                          GdkWindowTypeHint    hint)
 {
+  GtkWindowPrivate *priv;
+
   g_return_if_fail (GTK_IS_WINDOW (window));
   g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
-  window->type_hint = hint;
+
+  priv = GTK_WINDOW_GET_PRIVATE (window);
+
+  if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
+    window->type_hint = hint;
+  else
+    window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+
+  priv->reset_type_hint = TRUE;
+  priv->type_hint = hint;
 }
 
 /**
@@ -1996,9 +2016,13 @@ gtk_window_set_type_hint (GtkWindow           *window,
 GdkWindowTypeHint
 gtk_window_get_type_hint (GtkWindow *window)
 {
+  GtkWindowPrivate *priv;
+  
   g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
 
-  return window->type_hint;
+  priv = GTK_WINDOW_GET_PRIVATE (window);
+  
+  return priv->type_hint;
 }
 
 /**
@@ -3956,6 +3980,12 @@ gtk_window_finalize (GObject *object)
       window->keys_changed_handler = 0;
     }
 
+  if (window->screen)
+    {
+      g_signal_handlers_disconnect_by_func (window->screen,
+                                           gtk_window_on_composited_changed, window);
+    }
+      
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -4101,6 +4131,17 @@ gtk_window_map (GtkWidget *widget)
   window->need_default_size = FALSE;
   window->need_default_position = FALSE;
   
+  if (priv->reset_type_hint)
+    {
+      /* We should only reset the type hint when the application
+       * used gtk_window_set_type_hint() to change the hint.
+       * Some applications use X directly to change the properties;
+       * in that case, we shouldn't overwrite what they did.
+       */
+      gdk_window_set_type_hint (widget->window, priv->type_hint);
+      priv->reset_type_hint = FALSE;
+    }
+
   gdk_window_show (widget->window);
 
   if (window->frame)
@@ -4312,8 +4353,8 @@ gtk_window_realize (GtkWidget *widget)
   if (!priv->deletable)
     gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
 
-  gdk_window_set_type_hint (widget->window, window->type_hint);
-
+  gdk_window_set_type_hint (widget->window, priv->type_hint);
   if (gtk_window_get_skip_pager_hint (window))
     gdk_window_set_skip_pager_hint (widget->window, TRUE);
 
@@ -6866,13 +6907,30 @@ gtk_window_set_screen (GtkWindow *window,
   window->screen = screen;
   gtk_widget_reset_rc_styles (widget);
   if (screen != previous_screen)
-    _gtk_widget_propagate_screen_changed (widget, previous_screen);
+    {
+      g_signal_handlers_disconnect_by_func (previous_screen,
+                                           gtk_window_on_composited_changed, window);
+      g_signal_connect (screen, "composited_changed", 
+                       G_CALLBACK (gtk_window_on_composited_changed), window);
+      
+      _gtk_widget_propagate_screen_changed (widget, previous_screen);
+      _gtk_widget_propagate_composited_changed (widget);
+    }
   g_object_notify (G_OBJECT (window), "screen");
 
   if (was_mapped)
     gtk_widget_map (widget);
 }
 
+static void
+gtk_window_on_composited_changed (GdkScreen *screen,
+                                 GtkWindow *window)
+{
+  gtk_widget_queue_draw (GTK_WIDGET (window));
+  
+  _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
+}
+
 static GdkScreen *
 gtk_window_check_screen (GtkWindow *window)
 {
index 884b250f5d555b0644ee000846a34f156e3400a5..f022bb9eb13119f365c30a1002ce35144b83292f 100644 (file)
@@ -94,7 +94,9 @@ struct _GtkWindow
   guint maximize_initially : 1;
   guint decorated : 1;
   
-  guint type_hint : 3; /* GdkWindowTypeHint */ 
+  guint type_hint : 3; /* GdkWindowTypeHint if the hint is one of the original eight. If not, then
+                       * it contains GDK_WINDOW_TYPE_HINT_NORMAL
+                       */
   guint gravity : 5; /* GdkGravity */
 
   guint is_active : 1;
index dec2cad874e3fa5d38462e4b7af8ec5be563c665..080eec9c14faaec7b9580ec6db2457d189a6bc08 100644 (file)
@@ -170,7 +170,8 @@ on_alpha_window_expose (GtkWidget      *widget,
                                         widget->allocation.height / 2,
                                         radius * 1.33);
 
-  if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)))
+  if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) &&
+      gtk_widget_is_composited (widget))
     cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
   else
     cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
@@ -354,6 +355,18 @@ on_alpha_screen_changed (GtkWidget *widget,
   gtk_widget_set_colormap (widget, colormap);
 }
 
+static void
+on_composited_changed (GtkWidget *window,
+                     GtkLabel *label)
+{
+  gboolean is_composited = gtk_widget_is_composited (window);
+
+  if (is_composited)
+    gtk_label_set_text (label, "Composited");
+  else
+    gtk_label_set_text (label, "Not composited");
+}
+
 void
 create_alpha_window (GtkWidget *widget)
 {
@@ -379,22 +392,26 @@ create_alpha_window (GtkWidget *widget)
                          TRUE, TRUE, 0);
 
       label = gtk_label_new (NULL);
-      
       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
-      gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
-      gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
-
       on_alpha_screen_changed (window, NULL, label);
       g_signal_connect (window, "screen-changed",
                        G_CALLBACK (on_alpha_screen_changed), label);
       
+      label = gtk_label_new (NULL);
+      gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+      on_composited_changed (window, GTK_LABEL (label));
+      g_signal_connect (window, "composited_changed", G_CALLBACK (on_composited_changed), label);
+      
+      gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
+      gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
+
       g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed),
                        &window);
       
       g_signal_connect (window, "response",
                         G_CALLBACK (gtk_widget_destroy),
-                        NULL);
+                        NULL); 
     }
 
   if (!GTK_WIDGET_VISIBLE (window))